﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VirtualTournaments.Biz.Tournaments;

namespace VirtualTournaments.Biz.Bets
{
    class MatchBet : Bet
    {

        private Match _match;
        private MatchResultPrediction _expectedResult;

        public MatchBet(Match match, MatchResultPrediction expectedResult, double moneyToBet)
        {
            this._match = match;
            this._expectedResult = expectedResult;
            this.MoneyWagered = moneyToBet;
        }

        /// <summary>
        /// La cuenta que debería hacer es:
        /// Sumatoria del Monto de todas las apuestas que sean sobre el mismo partido * (1 - porcentaje de beneficio de la agencia) / Monto de apuestas ganadoras 
        /// </summary>
        /// <param name="currentBets"></param>
        public override void calculateOdds(Agency agency, Bet[] otherBets)
        {

            var sameKindBets = from bet in otherBets.AsQueryable()
                               where this.SameKind(bet)
                               select bet;
            var sameKindAndTargetBets = from bet in sameKindBets
                                        where this.SameTarget(bet)
                                        select bet;

            this.Odds = agency.calculateOddsForBet(sameKindBets.Sum(bet => bet.MoneyWagered), sameKindAndTargetBets.Sum(bet => bet.MoneyWagered), this.MoneyWagered);
        }

        /// <summary>
        /// Devuelve true si la apuesta es del mismo tipo y ademas apuesta al mismo objetivo
        /// </summary>
        /// <param name="bet"></param>
        /// <returns></returns>
        private bool SameTarget(Bet otherBet)
        {
            if (this.SameKind(otherBet))
            {
                MatchBet otherMatchBet = (MatchBet)otherBet;
                return this._match.Equals(otherMatchBet._match) && (this._expectedResult.CompareTo(otherMatchBet._expectedResult) == 0);
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Devuelve true si la apuesta es del mismo tipo
        /// </summary>
        /// <param name="bet"></param>
        /// <returns></returns>
        private bool SameKind(Bet otherBet)
        {
            return otherBet.GetType().IsInstanceOfType(this);
        }

        public override bool won()
        {
            MatchResultPrediction result;
            if (_match.getWinner() == _match.Local)
            {
                result = MatchResultPrediction.Local;
            }
            else if (_match.getWinner() == _match.Visitor)
            {
                result = MatchResultPrediction.Visitor;
            }
            else
            {
                result = MatchResultPrediction.Draw;
            }
            return result.CompareTo(this._expectedResult) == 0;
        }
    }
}
